<?php
class fs_smb extends fs_base {
    ######################################
    # Requires
    # nmap - for smb scanning
    # smbclient - accessing smb shares
	function fs_load () {
		$this->cred_req = true;
	}
    private function getlocalip () {
        $ret = exec("ifconfig", $lines);
        foreach($lines as $line) {
            if (strpos($line, "inet ") == "1") {
                $war = explode(" ", $line);
                if ($war[1] != "127.0.0.1") {
                    return $war[1];
                    break;
                }
            }
        }
    }
    private function getsubnet () {
    	$cmd = 'whoami';
    	passthru($cmd);

        exec("ifconfig", $lines = array(), $ret);
        if ($ret == 0) {
	        foreach($lines as $line) {
	        	$line = trim($line);
	            if (strpos($line, "inet ") == "1") {
	                $war = explode(" ", $line);
	                if ($war[1] != "127.0.0.1") {
	                    $subnet = substr($war[1], "0", strrpos($war[1], "."));
	                    return $subnet . '.';
	                    break;
	                }
	            }
	        }
        } else {
        	echo "Error<br/>\n";

        }
    }
    function browse($newpath) {
        $purl['scheme']= '';
        $purl['host'] = '';
        $purl['path'] = '';
        $purl['login'] = '';
        $purl['password'] = '';
        if (strpos(strtolower($newpath), "$this->scheme://") === 0) {
            error_reporting(0);
            $purl = parse_url($newpath);
            error_reporting(E_ALL & ~E_NOTICE);
            if ($purl['scheme'] != $this->scheme) {
                $stop_here = '';
            }
            $host = $purl['host'];
            $user = $purl['user'];
            $pass = $purl['pass'];
            $purl['path'] = $this->clean($purl['path'], '/', true);
            $pntr = strpos($purl['path'], '/');
            if ($pntr > 0) {
                $share = substr($purl['path'], 0, $pntr);
                $path = substr($purl['path'], $pntr);
            } else {
                $share = $purl['path'];
                $path = '';
            }
			if ($user != '' && $this->user != $user) {
				$this->user = $user;
				$this->pass = '';
			}
        	if ($pass != '' && $this->pass != $pass) {
				$this->pass = $pass;
			}

            $directory = substr($newpath, strlen("$this->scheme://"));
            #$directory = rtrim($directory, '/');
            //$this->build_quick_link($this->scheme, $directory);


            #### Quick Link End
            if ($host == '') {
                return $this->subnet_scan();
            } elseif ($share == '') {
                return $this->share_list($host,$user,$pass);
            } else {
                return $this->dir($host,$user,$pass,$share,$path);
            }
        }
    }
    private function subnet_scan () {
        $localsubnet = $this->getsubnet();
        $fullcmd = "nmap --system-dns -sS -p 139 $localsubnet" . "1-255";
        $ret = exec($fullcmd, $dirout);
        $listing = false;
        $skipline = false;
        $user = '';
        $pass = '';
        foreach ($dirout as $line) {
            if (!$skipline) {
                if (strpos($line, 'Interesting ports on ') === 0) {
                    $listing = true;
                    $line = substr($line, strlen('Interesting ports on '));
                    $ipaddress = substr($line, 0, strlen($line) - 1);
                    $skipline = true; # the next line is just a header line (PORT    STATE SERVICE     VERSION)
                } elseif ($line == '' and $listing) {
                    $listing = false;
                    if ($smbon) {
                        $thisdevice['ip'] = $ipaddress;
                        $thisdevice['mac'] = $macaddress;
                        $thisdevice['macvendor'] = $macvendor;
                        $thisdevice['smb'] = $smbon;
                        $devicearr[] = $thisdevice;
                    }
                    $ipaddress = '';
                    $macaddress = '';
                    $macvendor = '';
                    $port = '';
                    $smbon= false;
                } elseif ($listing) {
                    if (strpos($line, 'MAC Address: ') === 0) {
                        $line = substr($line, strlen('MAC Address: '));
                        $pntr = strpos($line, ' ');
                        if (strpos($line, ' ') > 0) {
                            $macaddress = substr($line, 0, strpos($line, ' '));
                            $macvendor = substr($line, strpos($line, ' ') + 1);
                            $macvendor = substr($macvendor, 1, strlen($macvendor) - 2);
                        } else {
                            $macaddress = $line;
                            $macvendor = 'Unknown';
                        }
                    } elseif (preg_match('#^[0-9]{1,5}\/#', $line, $matches) == 1) {
                        $port = substr($matches[0], 0,strlen($matches[0]) - 1);
                        if ($port == 139) {
                            # in this case the port will always be 139
                            $line = substr($line, strpos($line, ' ') + 1);
                            if (strpos($line, 'closed') === 0) {
                                $smbon = false;
                            } elseif (strpos($line, 'open') === 0) {
                                $smbon = true;
                            }
                        }
                    }
                }
            } else {
                $skipline = false;
            }
        }
        # Now show the results
        #$this->build_quick_link($host,$user,$pass,$share,$path);
        $thisimg = '/lib/images/mac-48x48.png';
        foreach ($devicearr as $adev) {
            $ipaddress = $adev['ip'];
            $inputid = $this->add_hidden_input("$this->scheme://$ipaddress");
            $applink = $this->run("browse_smb($inputid:value)->$this->target_id",$this->thisfile);
            #$applink = $this->run("browse_smb('$this->scheme://".$ipaddress."')->$this->target_id",$this->thisfile);
            $res['title'] = $ipaddress;
            $res['link'] = $applink;
            $res['img'] = $thisimg;
            if ($adev['mac'] != '') {
                $res['details'] = $adev['mac'];
                if ($adev['macvendor'] != '') {
                    $res['details'] .= " - " . $adev['macvendor'];
                }
            } else {
                $res['details'] = '';
            }
            $results[] = $res;
        }
        $this->display_results($results);
    }
    private function share_list ($host, $user, $pass, $show_sys_shares = false) {
        $fullcmd = "/usr/bin/smbclient -L //$host -U$user%$pass";
        $ret = exec($fullcmd, $dirout);
        $listingtype = '';
        $sharecnt = 0;
        $add_share = false;
        $res = array();
        foreach ($dirout as $line) {
        	$add_share = false;
            if (strpos($line, "\t") === 0) {
                $line = substr($line, 1);
                if (strpos($line, "Sharename") === 0) {
                    $listingtype = 'shares';
                } elseif (strpos($line, '--------') === 0) {
                    # Just ignore this line
                } else {
                    switch ($listingtype) {
                        case 'shares' :
                            $pntr = strpos($line, " ");
                            $sharename = substr($line, 0, $pntr);
                            $line = substr($line, $pntr + 1);
                            $line = trim($line);
                            $pntr = strpos($line, " ");
                            if ($pntr > 0) {
                                $sharetype = substr($line, 0, $pntr);
                                $line = substr($line, $pntr + 1);
                                $sharecomment = trim($line);
                            } else {
                                $sharetype = trim($line);
                                $sharecomment = '';
                            }
                            if (strlen($sharename) - 1 == strrpos($sharename,"$")) {
                                if ($show_sys_shares) {
                                    $add_share = true;
                                }
                            } else {
                                $add_share = true;
                            }
							if ($add_share) {
								$f = new fs_file();
								$f->name = $sharename;
								$f->isDir = true;
								$f->isFile = !$f->isDir;
								$f->type = $sharetype;
//								$f->modified = $file->getMTime();
//								$f->isFile = $file->isFile();
//								$f->isDir = !$f->isFile;
//								$f->path = $file->getPath();
//								$f->realPath = $file->getRealPath();
//								$f->isReadable = $file->isReadable();
//								$f->isWritable = $file->isWritable();
//								$f->isExecutable = $file->isExecutable();
//								$f->size = $file->getSize();
								$res[] = $f;
							}

                            break;
                        default :
                            break;
                    }
                }
            } else {
                $listingtype = '';
            }
        }
		$this->files = $res;
		$this->real_path = $this->scheme . "://" . $user . ":" . $pass . "@" . $host . "/";
		$this->path = $this->real_path;
		return true;
    }
    private function dir ($host, $user, $pass, $share, $folder) {
        $folder = $this->clean('\\' . $folder, '\\',false);
        if ($folder != '\\') {
            $folder = rtrim($folder,'\\');
        }
        $fullcmd = '/usr/bin/smbclient //' . $host . '/' . $share;
        if ($user != '') {
            $fullcmd .= ' -U ' . $user;
            if ($pass != '') {
                $fullcmd .= '%' . $pass;
            }
        }
        if ($folder != '') {
            $fullcmd .= " -c 'cd \"$folder\"; dir; exit;'";
        } else {
            $fullcmd .= " -c 'dir; exit;'";
        }
        $ret = exec($fullcmd, $dirout);
        $listing = true;
        $res = array();
        foreach ($dirout as $line) {
            $line = trim($line);
            if ($listing and $line != '') {
                if (substr_count($line, "\t") == 0) {
                    $flastmod = '';
                    $fl = $line;
                    for ($i=1;$i<=5;$i++) {
                        $pntr = strrpos($line, ' ');
                        $flastmod = substr($line, $pntr) . $flastmod;
                        $line = substr($line, 0, $pntr);
                        $line = trim($line);
                    }
                    $pntr = strrpos($line, ' ');
                    $fsize = substr($line, $pntr + 1);
                    $line = substr($line, 0, $pntr);
                    $line = trim($line);
                    if (substr_count($line, ' ') == 0) {
                        $fname = $line;
                        $ftype = '';
                    } else {
                        $pntr = strrpos($line, ' ');
                        $ftype = substr($line, $pntr + 1);

                        $line = substr($line, 0, $pntr);
                        $fname = trim($line);
                    }
                    if ($fname != '.' and $fname != '..') {
                        if ($fname != '') {
							$f = new fs_file();
							$file = new SplFileInfo($fname);
							$f->name = $fname;
							$f->path = $file->getPath();
							$f->realPath = $f->path;
							$f->size = $fsize;
							$f->type = $ftype;
							$f->modified = $flastmod;
							if (strpos($ftype,'D') === 0 || strpos($ftype,'D') > 0){
								$f->isDir = true;
								$f->type = 'Folder';
                        	} else {
                        		$f->isDir = false;
                        		$f->type = 'File';
                        	}
                        	$f->isFile = !$f->isDir;
//							$f->path = $file->getPath();
//							$f->realPath = $file->getRealPath();
//							$f->isReadable = $file->isReadable();
//							$f->isWritable = $file->isWritable();
//							$f->isExecutable = $file->isExecutable();
							$res[] = $f;
                        }
                    }
                }
            } else {
                $listing = false;
            }
        }
        $folder = str_replace('\\','/',$folder);
		$this->files = $res;
		$this->real_path = $this->scheme . "://" . $user . ":" . $pass . "@" . $host . "/" . $share . $folder;
		$this->path = $this->real_path;
		return true;
    }
    function cmd ($host, $user, $pass, $share, $command) {
        $fullcmd = 'smbclient //' . $host . '/' . $share;
        if ($user != '') {
            $fullcmd .= ' -U ' . $user;
            if ($pass != '') {
                $fullcmd .= '%' . $pass;
            }
        }
        $fullcmd .= ' -c \'' . $command . '; exit;\'';
        echo $fullcmd . "<br />\n";
        $ret = trim(shell_exec($fullcmd));
        $ret .= "<br />\nDone.<br />\n";
        return $ret;
    }
    function get ($host, $user, $pass, $share, $srcfile, $destfile) {
        $srcfile = $this->clean($srcfile, '\\',false);
        $destfile = $this->clean($destfile, '/',false);
        $fullcmd = '/usr/bin/smbclient //' . $host . '/' . $share;
        if ($user != '') {
            $fullcmd .= ' -U ' . $user;
            if ($pass != '') {
                $fullcmd .= '%' . $pass;
            }
        }
        $fullcmd .= " -c 'get \"$srcfile\" \"$destfile\";'";
        $ret = $fullcmd . " at " . time() . "<br />\n";
        $shell_ret = '';
        $shell_ret = shell_exec($fullcmd);
        if ($shell_ret == '') {
            $ret .= "File transfered.<br />\n";
        } else {
            $ret .= "$shell_ret<br />\nError<br />\n";
        }
        return $ret;
    }
    function put ($host, $user, $pass, $share, $srcfile, $destfile) {
        $srcfile = $this->clean($srcfile, '\\',false);
        $destfile = $this->clean($destfile, '/',false);
        $fullcmd = '/usr/bin/smbclient //' . $host . '/' . $share;
        if ($user != '') {
            $fullcmd .= ' -U ' . $user;
            if ($pass != '') {
                $fullcmd .= '%' . $pass;
            }
        }
        $fullcmd .= " -c 'put \"$srcfile\" \"$destfile\";'";
        $ret = $fullcmd . " at " . time() . "<br />\n";
        $shell_ret = '';
        $shell_ret = shell_exec($fullcmd);
        if ($shell_ret == '') {
            $ret .= "File transfered.<br />\n";
        } else {
            $ret .= "$shell_ret<br />\nError<br />\n";
        }
        return $ret;
    }
    private function clean($path, $use_slash, $remove_preceding_slash) {
        $path = trim($path);
        if ($use_slash == '') {
            $use_slash = '/';
        }
        if (empty($path)) {
            $path = JPATH_ROOT;
        } else {
            // Remove double slashes and backslahses and convert all slashes and backslashes to DS
            $outpath = ereg_replace("\.[\.]+", "", $path);
            if ($remove_preceding_slash) {
                $outpath = ereg_replace("^[\/]+", "", $outpath);
            }
            $outpath = preg_replace('#[/\\\\]+#', $use_slash, $outpath);
            $outpath = ereg_replace("^[A-Za-z][:\|][\/]?", "", $outpath);
        }
        return $outpath;
    }

######################################
}
?>